#include "globals.h"

void error(char *msg){
	printf("%s:%i:%i: error: %s\n", __filename, __line, __column, msg);
}

void warring(char *msg){
	printf("%s:%i:%i: warring: %s\n", __filename, __line, __column, msg);	
}

void notice(char *msg){
	printf("%s:%i:%i: notice: %s\n", __filename, __line, __column, msg);	
}

char *strdcat(char *a, char *b){
	unsigned len=strlen(a)+strlen(b)+1;
	char *ret=(char*)malloc(len);
	strcpy(ret, a);
	strcat(ret, b);
	return ret;	
}

void dumpElement(Element *el, int depth){
//	char *elNames[]={"CODE_BLOCK", "DECLARATION"};
	
	if(el==0) return;
	
	int i;
	for(i=0;i<depth;i++)
		putc(' ', stdout);
	
	printf("ELEMENT TYPE: %i\n", el->type);
	
//	if(el->type==CODE_BLOCK)
//		dumpElement(el->content, depth+1);
	dumpElement(el->next, depth);
}

void dumpParseTree(void){
	puts("/***\nPARSE TREE DUMP");
	printf("PACKAGE: %s\n", program->class->package);
	puts("IMPORTS");
	
	Import *imp=program->imports;
	for(;imp;imp=imp->next)
		printf("  IMPORT: %s \n", imp->fullname);
		
	puts("CLASS");
	printf("  NAME: %s PARENT: %s\n", program->class->name, program->class->parent);
	
	puts("VARIABLES");
	Variable *v=program->class->vars;
	for(;v;v=v->next)
		printf("  VAR: %s OF TYPE %s\n", v->name, v->type);
		
	puts("CONSTRUCTORS");
	int i=0;
	Method *m=program->class->constructors;
	for(;m;m=m->next) {
		printf("  CONSTRUCTOR: %i\n", i++);
		
		puts("    ARGUMENTS");
		for(v=m->args;v;v=v->next)
			printf("      ARG: %s OF TYPE %s\n", v->name, v->type);
		
		puts("    CODE");	
		dumpElement(m->code, 6);	
	}
		
	puts("METHODS");
	for(m=program->class->methods;m;m=m->next) {
		printf("  METHOD: %s OF TYPE %s\n", m->name, m->type);
		
		puts("    ARGUMENTS");
		v=m->args;
		//printf("      ARG: %u OF TYPE %u\n", v->name, v->type);
		for(v=m->args;v;v=v->next)
			printf("      ARG: %s OF TYPE %s\n", v->name, v->type);	
			
		puts("    CODE");	
		dumpElement(m->code, 6);		
	}
		
	puts("\n***/");
}

char *md5string(char *str){
	md5_state_t state;
	md5_byte_t digest[16];
	char hex_output[16*2 + 1];

	md5_init(&state);
	md5_append(&state, (const md5_byte_t *)str, strlen(str));
	md5_finish(&state, digest);
	
	int di;
	for (di = 0; di < 16; ++di)
	    sprintf(hex_output + di * 2, "%02x", digest[di]);	
	
	return strdup(hex_output);
}

char *translateType(char *typeName){
//	printf("//%s\n", typeName);
	if(typeName[0]=='*')	return strdup("void *");
	else if(typeName[0]=='|')	return strdup("void *");
	else if(strcmp(typeName, "void")==0)	return strdup("void");
	else if(strcmp(typeName, "char")==0)	return strdup("char");
	else if(strcmp(typeName, "short")==0)	return strdup("short");
	else if(strcmp(typeName, "int")==0)	return strdup("int");
	else if(strcmp(typeName, "long")==0)	return strdup("long");
	else if(strcmp(typeName, "float")==0)	return strdup("float");
	else if(strcmp(typeName, "double")==0)	return strdup("double");
	else if(strcmp(typeName, "bool")==0)	return strdup("int");
	else	return strdup("Class *");
}

